package info.liuxing.config;

import info.liuxing.bean.Color;
import info.liuxing.bean.ColorFactoryBean;
import info.liuxing.bean.Person;
import info.liuxing.bean.Red;
import info.liuxing.condition.LinuxCondition;
import info.liuxing.condition.MyImportBeanDefinitionRegistrar;
import info.liuxing.condition.MyImportSelector;
import info.liuxing.condition.WindowsCondition;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.*;

/**
 * MainConfig2
 *
 * @author liuxing
 * @summary MainConfig2
 * @Copyright (c) 2018, Lianjia Group All Rights Reserved.
 * @since 2018-04-08 22:19
 */
@Slf4j
//条件判断也可以是方法级
//@Conditional(value = WindowsCondition.class)

// 快速给容器中导入一个组件，默认包名是组件类全名
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
@Configuration
public class MainConfig2 {

    /**
     * prototype 多实例 IOC初始化时不会创建对象注册到容器，而是每次获取的时候创建对象
     * singleton 单例 默认IOC初始化就会注册到容器中，之后每次获取都是从容器cache中直接返回已有实例
     * request 同一次请求创建一个实例 （web环境）
     * session 统一个session创建一个实例 （web环境）
     * <p>
     * 懒加载
     * 单例bean：默认在容器启动时，初始化bean
     * 懒加载：默认在容器启动时不初始化bean，当第一次获取的时候再初始化bean
     *
     * @return
     */
    @Lazy
    @Scope("singleton")
    @Bean(name = "person")
    public Person person() {
        log.info("给容器中添加Person...");
        return new Person("张三", 18);
    }

    /**
     * 指定条件判断
     *
     * @return
     */
    @Conditional(value = WindowsCondition.class)
    @Bean(name = "windows")
    public Person windows() {
        log.info("给容器中添加Person...");
        return new Person("windows", 18);
    }

    /**
     * 指定条件判断
     *
     * @return
     */
    @Conditional(value = LinuxCondition.class)
    @Bean(name = "linux")
    public Person linux() {
        log.info("给容器中添加Person...");
        return new Person("linux", 18);
    }

    /**
     * 给容器中注册组件
     * 1、包扫描+组件标准注解(@Controller、@Service、@Component等)[局限于自己项目的类]
     * 2、@Bean [导入第三方包组件]
     * 3、@Import [快速给容器中导入一个组件]
     *      1、@Import(要导入到容器中的组件)，容器中就会自动注册这个组件，id默认是全类名
     *      2、ImportSelector：返回需要导入的组件的全类名的数组；
     *      3、ImportBeanDefinitionRegistrar：手动注册bean到容器中
     * 4、使用spring提供的 FactoryBean（工程Bean）
     *      1、默认获取到的是工厂Bean调用getObject创建的对象
     *      2、要获取工厂Bean本身，需要给id前面加一个&标识
     *
     */
    @Bean
    public ColorFactoryBean colorFactoryBean() {
        return new ColorFactoryBean();
    }
}
